package cn.symbio.service.service.impl;

import cn.symbio.basic.config.BussinessException;
import cn.symbio.basic.util.AjaxResult;
import cn.symbio.basic.util.CodeGenerateUtils;
import cn.symbio.order.domain.OrderPetAcquisition;
import cn.symbio.order.domain.OrderProduct;
import cn.symbio.order.mapper.OrderProductMapper;
import cn.symbio.org.domain.Employee;
import cn.symbio.org.mapper.EmployeeMapper;
import cn.symbio.service.domain.Product;
import cn.symbio.service.domain.ProductOnlineAuditLog;
import cn.symbio.service.domain.ProductUntreated;
import cn.symbio.service.domain.ResponseMsg;
import cn.symbio.service.dto.AcceptDto;
import cn.symbio.service.mapper.ProductOnlineAuditLogMapper;
import cn.symbio.service.mapper.ProductUntreatedMapper;
import cn.symbio.service.service.IProductUntreatedService;
import cn.symbio.basic.service.impl.BaseServiceImpl;
import com.baomidou.mybatisplus.extension.api.R;
import io.swagger.models.auth.In;
import org.apache.rocketmq.client.MQAdmin;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author bitter
 * @since 2022-11-03
 */
@Service
public class ProductUntreatedServiceImpl extends BaseServiceImpl<ProductUntreated> implements IProductUntreatedService {


    @Autowired
    private ProductUntreatedMapper productUntreatedMapper;

    @Autowired
    private ProductOnlineAuditLogMapper productOnlineAuditLogMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private OrderProductMapper orderProductMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    /**
     * 接单
     * @param dto
     * @return
     */
    @Override
    public AjaxResult accept(AcceptDto dto) {
        // 数据校验
        ProductUntreated productUntreated = productUntreatedMapper.findById(dto.getProductId());
        if (productUntreated == null) {
            throw new BussinessException("当前服务不存在！！！");
        }
        // 解决线程安全问题
        synchronized (productUntreated.getId()){
            // 判断当前接单人是否存在
            Employee employee = employeeMapper.findById(dto.getHandler());
            if (employee == null) {
                throw new BussinessException("接单员工不存在！！！");
            }
            // 修改状态为已接单
            productUntreated.setState(1);
            productUntreatedMapper.update(productUntreated);
            // 生成订单
            OrderProduct orderProduct = initOrder(dto, productUntreated);
            orderProductMapper.add(orderProduct);
            // mq发送定时消息
            String messageStr = "orderId:" + orderProduct.getId();
            // 编写消息
            Message<String> message = MessageBuilder.withPayload(messageStr)
                    .setHeader(RocketMQHeaders.KEYS, orderProduct.getId())
                    .build();
            // 设置发送地和消息信息并发送延时消息
            SendResult sendResult = rocketMQTemplate.syncSend("anran-topic:anran-sync-tags", message,1*1000l,5);
            // System.out.println(System.currentTimeMillis());
            // 不ok就报错
            if (sendResult.getSendStatus() != SendStatus.SEND_OK) {
                throw new BussinessException("消息发送失败");
            }
            return AjaxResult.me();
        }
    }

    private OrderProduct initOrder(AcceptDto dto, ProductUntreated productUntreated) {
        // 产生订单
        return OrderProduct
                .builder()
                .digest(dto.getNote())
                .price(productUntreated.getSaleprice())
                .orderSn(CodeGenerateUtils.generateOrderSn(10))
                .paySn(CodeGenerateUtils.generateOrderSn(2))
                .lastPayTime(new Date(System.currentTimeMillis() + 15 * 60 * 1000))
                .lastConfirmTime(new Date(System.currentTimeMillis() + 3 * 24 * 60 * 60 * 1000))
                .productId(productUntreated.getId())
                .state(0)
                .userId(productUntreated.getUserId())
                .build();
    }

    /**
     * 拒单
     * @param id
     * @return
     */
    @Override
    public AjaxResult reject(Long id) {
        // 数据校验
        ProductUntreated productUntreated = productUntreatedMapper.findById(id);
        if (productUntreated == null) {
            throw new BussinessException("当前服务不存在！！！");
        }
        // 添加拒单日志
        addLog(productUntreated,0,"成功拒单！！");
        productUntreated.setState(-1);
        productUntreatedMapper.update(productUntreated);
        return AjaxResult.me();
    }

    /**
     * 下单
     * @param product
     * @return
     */
    @Override
    public AjaxResult addProduct(Product product) {
        // 参数校验，，，，
        if (product.getName() == null || product.getResources() == null) {
            throw new BussinessException("当前服务不存在！！！");
        }
        ProductUntreated productUntreated = initProductUntreated(product);
        add(productUntreated);
        return AjaxResult.me();
    }

    // 初始化ProductUntreated
    private ProductUntreated initProductUntreated(Product product) {
        return ProductUntreated
                .builder()
                .name(product.getName())
                .resources(product.getResources())
                .costprice(product.getCostprice())
                .saleprice(product.getSaleprice())
                .createtime(product.getCreatetime())
                .salecount(product.getSalecount())
                .shopId(product.getShopId())
                .sname(product.getSName())
                .userId(product.getUserId())
                .username(product.getUsername())
                .state(1)
                .build();
    }

    private void addLog(ProductUntreated productUntreated, Integer state, String note) {
        ProductOnlineAuditLog poal = new ProductOnlineAuditLog();
        poal.setProductId(productUntreated.getId());
        poal.setState(state);
        poal.setAuditTime(new Date());
        poal.setNote(note);
        productOnlineAuditLogMapper.add(poal);
    }
}
